package com.dietmanager.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;

import javafx.application.Application;
import javafx.stage.Stage;

import com.dietmanager.datalayer.DataLayer;
import com.dietmanager.model.DailyLogModel;
import com.dietmanager.model.Exercise;
import com.dietmanager.model.ExerciseModel;
import com.dietmanager.model.Food;
import com.dietmanager.model.FoodModel;
import com.dietmanager.model.Recipe;
import com.dietmanager.model.Workout;
import com.dietmanager.view.AddExerciseView;
import com.dietmanager.view.AddFoodView;
import com.dietmanager.view.AddRecipeView;
import com.dietmanager.view.AddWorkoutView;
import com.dietmanager.view.MainView;

public class Controller extends Application implements Observer {
	private ArrayList<FoodModel> foodModelArr;
	private ArrayList<ExerciseModel> exerciseModelArr;
	
	private DailyLogModel dailyLogModel;
	
	private DataLayer<ArrayList<FoodModel>> foodDataLayer;
	private DataLayer<ArrayList<ExerciseModel>> exerciseDataLayer;
	
	private DataLayer<DailyLogModel> dailyLogDataLayer;
	
	private MainView mainView;
	
	public static void main(String[] args) {
		launch(args);
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		// create food model
		foodDataLayer = new DataLayer<ArrayList<FoodModel>>(FoodModel.class.getName());
		foodModelArr = foodDataLayer.readFile();
		if(foodModelArr == null)
			foodModelArr = new ArrayList<FoodModel>();

		// create daily log model
		dailyLogDataLayer = new DataLayer<DailyLogModel>(DailyLogModel.class.getName());
		dailyLogModel = dailyLogDataLayer.readFile();
		if(dailyLogModel == null)
			dailyLogModel = new DailyLogModel();
		
		// create exercise model
		exerciseDataLayer = new DataLayer<ArrayList<ExerciseModel>>(ExerciseModel.class.getName());
		exerciseModelArr = exerciseDataLayer.readFile();
		if(exerciseModelArr == null)
			exerciseModelArr = new ArrayList<ExerciseModel>();
		
		// create main view
		mainView = new MainView(primaryStage);
		mainView.addObserver(this);

		ArrayList<FoodModel> fm = dailyLogModel.getFoods(new Date(2014,5,5));
		ArrayList<ExerciseModel> em = dailyLogModel.getExercises(new Date(2014,5,5));
		
		mainView.displayDailyLog(fm, em);
		mainView.updateFoodList(foodModelArr);
		mainView.updateExerciseList(exerciseModelArr);
	}
	
	public ArrayList<FoodModel> getFoodModelArr() {
		return foodModelArr;
	}

	public DailyLogModel getDailyLogModel() {
		return dailyLogModel;
	}

	public void addFood(FoodModel food) {
		foodModelArr.add(food);
		foodDataLayer.writeFile(foodModelArr);
	}

	public void addExercise(ExerciseModel exercise) {
		exerciseModelArr.add(exercise);
		exerciseDataLayer.writeFile(exerciseModelArr);
	}
	
	public void addDailyLog(Date date, int calorieLimit, int weight, FoodModel food) {
		if(!dailyLogModel.hasDailyLog(date))
			dailyLogModel.addDailyLog(date);
		
		dailyLogModel.setCalorieLimit(date, calorieLimit);
		dailyLogModel.setWeight(date, weight);
		dailyLogModel.addFood(date, food);
	}

	public void addDailyLog(Date date, int calorieLimit, int weight) {
		if(!dailyLogModel.hasDailyLog(date))
			dailyLogModel.addDailyLog(date);
		
		dailyLogModel.setCalorieLimit(date, calorieLimit);
		dailyLogModel.setWeight(date, weight);
	}

	public void addDailyLog(Date date) {
		if(!dailyLogModel.hasDailyLog(date)) {
			Date preDate = dailyLogModel.getPreviousDate(date);
			int calorieLimit;
			int weight;
			
			if(dailyLogModel.hasDailyLog(preDate)) {
				calorieLimit = dailyLogModel.getCalorieLimit(preDate);
				weight = dailyLogModel.getWeight(preDate);
			}
			else {
				calorieLimit = DailyLogModel.DEFAULT_CALORIE_LIMIT;
				weight = DailyLogModel.DEFAULT_WEIGHT;				
			}
				
			dailyLogModel.addDailyLog(date);
			dailyLogModel.setCalorieLimit(date, calorieLimit);
			dailyLogModel.setWeight(date, weight);
		}
	}
	
	public void addFoodToDailyLog(Date date, FoodModel food) {
		if(!dailyLogModel.hasDailyLog(date))
			addDailyLog(date);
		
		dailyLogModel.addFood(date, food);
	}
	
	public void addExerciseToDailyLog(Date date, ExerciseModel exercise) {
		if(!dailyLogModel.hasDailyLog(date))
			addDailyLog(date);
		
		dailyLogModel.addExercise(date, exercise);
	}
	
	@Override
	public void update(Observable o, Object arg) {
				
		if(o instanceof MainView && arg instanceof Date)
		{
			dailyLogDataLayer.writeFile(dailyLogModel);
			ArrayList<FoodModel> fm = dailyLogModel.getFoods(((Date)arg));
			ArrayList<ExerciseModel> em = dailyLogModel.getExercises(((Date)arg));
			mainView.displayDailyLog(fm, em);
		}
		else if(o instanceof AddFoodView && arg instanceof Food)
		{
			System.out.println("Called AddFoodView part");
			addFood((Food)arg);
			mainView.updateFoodList(foodModelArr);
		}
		else if(o instanceof AddExerciseView && arg instanceof Exercise)
		{
			System.out.println("Called AddExerciseView part");
			addExercise((Exercise)arg);
			mainView.updateExerciseList(exerciseModelArr);
		}
		else if(o instanceof MainView && arg instanceof String)
		{
			System.out.println("calling add food to daily log: " + arg);
			
			if(dailyLogModel.hasDailyLog(mainView.getSelectedDate()) == false)
				dailyLogModel.addDailyLog(mainView.getSelectedDate());
			
			FoodModel fm = null;
			
			for(FoodModel food : foodModelArr)
				if(food.getName() == arg)
					fm = food;
			
			addFoodToDailyLog(mainView.getSelectedDate(), fm);
			foodDataLayer.writeFile(foodModelArr);
			dailyLogDataLayer.writeFile(dailyLogModel);
			
			mainView.displayDailyLog(dailyLogModel.getFoods(mainView.getSelectedDate()),
					dailyLogModel.getExercises(mainView.getSelectedDate()));
		}
		else if(o instanceof MainView && arg instanceof StringBuilder)
		{
			if(dailyLogModel.hasDailyLog(mainView.getSelectedDate()) == false)
				dailyLogModel.addDailyLog(mainView.getSelectedDate());

			ExerciseModel em = null;
			
			for(ExerciseModel exercise : exerciseModelArr)
				if(exercise.getName().equals(arg.toString()))
					em = exercise;
			
			addExerciseToDailyLog(mainView.getSelectedDate(), em);
			exerciseDataLayer.writeFile(exerciseModelArr);
			dailyLogDataLayer.writeFile(dailyLogModel);
			
			mainView.displayDailyLog(dailyLogModel.getFoods(mainView.getSelectedDate()),
					dailyLogModel.getExercises(mainView.getSelectedDate()));
		}
		else if(o instanceof AddRecipeView && arg instanceof Recipe)
		{
			addFood((Recipe)arg);
			mainView.updateFoodList(foodModelArr);
		}
		else if(o instanceof AddWorkoutView && arg instanceof Workout)
		{
			addExercise((Workout)arg);
			mainView.updateExerciseList(exerciseModelArr);
		}
		
	}
}
